package org.kisekiproject.course {
	import flash.events.Event;
	
	import org.kisekiproject.evaluator.BindingExpression;
	import org.kisekiproject.evaluator.IExpression;

	/**
	 * Trigger.
	 */
	public class CourseTrigger {

		private var _course:CourseModel;
		private var _event:String;
		private var _pages:Array;
		private var _actions:Array;
		private var _criteria:Array;

		/**
		 * Constructor.
		 */
		public function CourseTrigger() {
		}

		/**
		 * Set course.
		 */
		public function set course(value:CourseModel):void {
			_course=value;
		}

		/**
		 * Parse Xml.
		 */
		public function parse(source:XML):void {
			_event=String(source.@event);

			if (!_event)
				throw new Error("Event not specified for trigger");

			_pages=_course.getMatchingPages(String(source.@from));

			for each (var page:CoursePage in _pages)
				page.addEventListener(Event.COMPLETE,onPageComplete);

			_actions=new Array();
			_criteria=new Array();

			for each (var actionXml:XML in source.children()) {
				if (String(actionXml.name())=="criteria") {
					var exp:BindingExpression=new BindingExpression(new String(actionXml.valueOf()),_course.variables);
					_criteria.push(exp);
				}

				else {
					var action:CourseActionCall=new CourseActionCall();
					action.course=_course;
					action.parse(actionXml);
					_actions.push(action);
				}
			}

			for each (var x:XML in source.attributes()) {
				if (String(x.name())=="criteria") {
					var ex:BindingExpression=new BindingExpression(new String(x.valueOf()),_course.variables);
					_criteria.push(ex);
				}
			}
		}

		/**
		 * Page complete, we can add listeners.
		 */
		protected function onPageComplete(event:Event):void {
			var page:CoursePage=CoursePage(event.target);
			page.displayObject.addEventListener(_event,onEvent);
		}
		
		/**
		 * Event was triggered.
		 */
		protected function onEvent(event:Event):void {
			//trace("got matching event...");

			for each (var criteria:IExpression in _criteria) {
				var v:Object=criteria.value;

				//trace("criteria val: "+v);

				if (!v)
					return;
			}

			for each (var action:CourseActionCall in _actions)
				action.call();
		}
	}
}